/**
 * 
 */
package de.cbf.cam.dsa.tavern.carte.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;

import de.cbf.cam.dsa.tavern.carte.exceptions.WrongTypeProvidedException;
import de.cbf.cam.dsa.tavern.carte.model.entities.Ingredient;
import de.cbf.cam.dsa.tavern.carte.model.entities.Processing;
import de.cbf.cam.dsa.tavern.carte.model.entities.interfaces.IEditableEntity;
import de.cbf.cam.dsa.tavern.carte.ui.CompositeEditProcessing;

import de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositeEditEntity;

/**
 * @author Stefan Alter
 *
 */
public class ControllerEditProcessing extends ControllerEditEntity {
	private Iterator<Ingredient> 	iteratorRootIngredients;
	
	/**
	 * 
	 */
	public ControllerEditProcessing() {		
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.tavern.carte.controller.ControllerEditEntity#checkEntity(de.cbf.cam.dsa.tavern.carte.model.entities.interfaces.IEditableEntity)
	 */
	@Override
	protected boolean checkEntity(IEditableEntity value)
			throws IllegalArgumentException {
		if (value instanceof Processing) {
			return true;
		}
		if(value == null){
			throw new WrongTypeProvidedException(Processing.class.getName(),"null");	
		}
		throw new WrongTypeProvidedException(Processing.class, value.getClass());		
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.tavern.carte.controller.ControllerEditEntity#checkView(de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositeEditEntity)
	 */
	@Override
	protected boolean checkView(ICompositeEditEntity value)
			throws IllegalArgumentException {
		if (value instanceof CompositeEditProcessing) {			
			return true;
		}
		if(value == null){
			throw new WrongTypeProvidedException(CompositeEditProcessing.class.getName(),"null");	
		}
		throw new WrongTypeProvidedException(CompositeEditProcessing.class, value.getClass());		
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.tavern.carte.controller.ControllerEditEntity#registerViewListeners(de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositeEditEntity)
	 */
	@Override
	protected boolean registerViewListenersAndInit(ICompositeEditEntity value) {
		if (value instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) value;
			//register view listeners
			composite.registerIngredientSelectionListener	(ingredientSelection);
			composite.registerCategorySelectionListener		(categorySelection);
			composite.registerNameModifyListener			(nameModify);
			composite.registerPriceModifyListener			(priceModify);
			composite.registerAddToAddendumsListener		(addIngredientToPossibleAddendumCategories);			
			composite.registerRemoveFromAddendumsListener	(removeIngredientFromPossibleAddendumCategories);
			//init view
			if(iteratorRootIngredients != null){
				//if we have a not yet applied iterator for root ingredients, we apply it
				composite.setIngredients(iteratorRootIngredients);
			}
			return true;
		}else{
			return false;
		}		
	}
	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.tavern.carte.controller.ControllerEditEntity#deRegisterViewListeners(de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositeEditEntity)
	 */
	@Override
	protected boolean deRegisterViewListeners(ICompositeEditEntity value) {
		if (value instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) value;
			composite.deRegisterIngredientSelectionListener	(ingredientSelection);
			composite.deRegisterCategorySelectionListener	(categorySelection);
			composite.deRegisterNameModifyListener			(nameModify);
			composite.deRegisterPriceModifyListener			(priceModify);
			composite.deRegisterAddToAddendumsListener		(addIngredientToPossibleAddendumCategories);			
			composite.deRegisterRemoveFromAddendumsListener	(removeIngredientFromPossibleAddendumCategories);
			return true;
		}else{
			return false;
		}		
	}
	
	@Override
	protected PropertyChangeListener getPCLforEntity() {		
		return pclProcessing;
	}
	private final PropertyChangeListener pclProcessing = new PCLProcessing();
	private class PCLProcessing implements PropertyChangeListener{
		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			if (view instanceof CompositeEditProcessing) {
				CompositeEditProcessing composite = (CompositeEditProcessing) view;
				if (evt instanceof IndexedPropertyChangeEvent) {					
//					IndexedPropertyChangeEvent idxEvent = (IndexedPropertyChangeEvent) evt;	
					//TODO fineGrain property update
					composite.setEntity(entity);
				}else{
					//brutal update, because we do not know which property changed
					composite.setEntity(entity);
				}
			}
				
		}		
	}
	
	
	public void setIngredients(Iterator<Ingredient> iteratorRootIngredients) {
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			composite.setIngredients(iteratorRootIngredients);
		}else{
			//if view is not yet active save the iterator of the root ingredients for later adding of ingredients
			this.iteratorRootIngredients = iteratorRootIngredients;
		}
	}	
	
	public void doIngredientSelection(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			composite.setButtonToAddendumsEnabled(true);
		}
	}
	
	public void doCategorySelection(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			composite.setButtonFromAddendumsEnabled(true);
		}
	}
	
	public void doNameModify(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			if (entity instanceof Processing) {
				Processing processing = (Processing) entity;
				processing.setName(composite.getProcessingName());
				testUnsavedChanges();
			}				
		}
	}
	
	public void doPriceModify(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			if (entity instanceof Processing) {
				Processing processing = (Processing) entity;
				processing.setModifiedPrice(composite.getPrice());
				testUnsavedChanges();
			}				
		}
	}
	
	public void doAddIngredient(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			if (entity instanceof Processing) {
				Processing processing = (Processing) entity;					
				String category = composite.getSelectedIngredient().getName();
				processing.addPossibleAddendumCategory(category);
				testUnsavedChanges();
			}				
		}
	}
	
	public void doRemoveIngredient(){
		if (view instanceof CompositeEditProcessing) {
			CompositeEditProcessing composite = (CompositeEditProcessing) view;
			if (entity instanceof Processing) {
				Processing processing = (Processing) entity;
				String category = composite.getSelectedAddendumCategory();
				processing.removePossibleAddendumCategory(category);
				composite.setButtonFromAddendumsEnabled(false);
				testUnsavedChanges();
			}				
		}
	}
	
	private IngredientSelection ingredientSelection = new IngredientSelection();	
	private class IngredientSelection implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doIngredientSelection();
		}		
	}
	private CategorySelection categorySelection = new CategorySelection();	
	private class CategorySelection implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doCategorySelection();
		}		
	}	
	private NameModify nameModify = new NameModify();	
	private class NameModify implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doNameModify();
		}		
	}
	private PriceModify priceModify = new PriceModify();	
	private class PriceModify implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doPriceModify();
		}		
	}	
	private AddIngredientToPossibleAddendumCategories addIngredientToPossibleAddendumCategories 
			= new AddIngredientToPossibleAddendumCategories();	
	private class AddIngredientToPossibleAddendumCategories implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doAddIngredient();
		}		
	}	
	private RemoveIngredientFromPossibleAddendumCategories removeIngredientFromPossibleAddendumCategories 
			= new RemoveIngredientFromPossibleAddendumCategories();	
	private class RemoveIngredientFromPossibleAddendumCategories implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			doRemoveIngredient();
		}		
	}
	
	
}
